/*
 =============================================================================
 FILE...............: AirportDAO.java
 COMMENTS...........: Class implemented by using the DAO (Data Access Object)
 					  design pattern for manipulating Airport objects while
 					  accessing the database. This class extends the GenericDAO
 					  abstract class.
 =============================================================================
 AUTHOR(S)..........: Everton Ranielly de Sousa Cavalcante
 					  Department of Informatics and Applied Mathematics
 					  Federal University of Rio Grande do Norte
 LAST MODIFICATION..: September 17th, 2012
 ============================================================================= 					  
*/


/* ========================================================================= */
/* PACKAGES			                                                         */
/* ------------------------------------------------------------------------- */
package dao;


/* ========================================================================= */
/* IMPORTS			                                                         */
/* ------------------------------------------------------------------------- */
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import model.Airport;


/* ========================================================================= */
/* CLASS AirportDAO                                                          */
/* ------------------------------------------------------------------------- */
/**
 * Class implemented by using the DAO (Data Access Object) design pattern for 
 * manipulating <code>Airport</code> objects while accessing the database. 
 * This class extends the <code>GenericDAO</code> abstract class.
 * @author Everton Cavalcante
 */
public class AirportDAO extends GenericDAO<Airport, String>
{
	/** Default constructor */
	public AirportDAO()
	{ /* Empty */ }
	
	
	/**
	 * Inserts an airport
	 * @param airport Airport to insert
	 */
	public void insert(Airport airport)
	{		
		try 
		{
			// Opens a connection 
			openConnection();
			
			// SQL query to be executed
			String query = "INSERT INTO airports VALUES(?,?,?,?)";
			pstmt = conn.prepareStatement(query);
			
			// Data to be inserted
			pstmt.setString(1, airport.getAirportIATACode());
			pstmt.setString(2, airport.getAirportICAOCode());
			pstmt.setString(3, airport.getAirportName());
			pstmt.setString(4, airport.getAirportLocation());
			
			// Executes query
			pstmt.execute();
		}
		catch (SQLException e) 
		{ 
			System.out.println("Error when inserting airport:\n" + e.getMessage());
			System.exit(1);
		}
		catch (IOException e)
		{
			e.printStackTrace();
			System.exit(1);
		}
		finally
		{ closeConnection(); }
	}
	
	
	/**
	 * Updates an airport
	 * @param airport Airport data to update
	 * @param code Airport code
	 */
	public void update(Airport airport, String code)
	{
		if (code.length() != 3 && code.length() != 4)
		{
			System.out.println("Error:\nInvalid airport code");
			System.exit(1);
		}
		else
		{
			try 
			{
				// Opens a connection 
				openConnection();
				
				// SQL query to be executed
				String criteria = (code.length() == 3) ? "airportiatacode" : "airporticaocode";
				String query = "UPDATE airports SET airportiatacode = ?, airporticaocode = ?, airportname = ?, airportlocation = ? " +
					"WHERE " + criteria + " = ?";
				pstmt = conn.prepareStatement(query);
				
				// Data to be updated
				pstmt.setString(1, airport.getAirportIATACode());
				pstmt.setString(2, airport.getAirportICAOCode());
				pstmt.setString(3, airport.getAirportName());
				pstmt.setString(4, airport.getAirportLocation());
				pstmt.setString(5, code);
				
				// Executes query
				pstmt.execute();
			}
			catch (SQLException e) 
			{ 
				System.out.println("Error when updating airport:\n" + e.getMessage());
				System.exit(1);
			}
			catch (IOException e)
			{
				e.printStackTrace();
				System.exit(1);
			}
			finally
			{ closeConnection(); }
		}
	}
	
	
	/**
	 * Deletes an airport
	 * @param code Airport code
	 */
	public void delete(String code)
	{
		if (code.length() != 3 && code.length() != 4)
		{
			System.out.println("Error:\nInvalid airport code");
			System.exit(1);
		}
		else
		{
			try 
			{
				// Opens a connection 
				openConnection();
				
				// SQL query to be executed
				String criteria = (code.length() == 3) ? "airportiatacode" : "airporticaocode";
				String query = "DELETE FROM airports WHERE " + criteria + " = ?";
				pstmt = conn.prepareStatement(query);
				
				// Data to be deleted
				pstmt.setString(1, code);
				
				// Executes query
				pstmt.execute();
			}
			catch (SQLException e) 
			{ 
				System.out.println("Error when deleting airport:\n" + e.getMessage());
				System.exit(1);
			}
			catch (IOException e)
			{
				e.printStackTrace();
				System.exit(1);
			}
			finally
			{ closeConnection(); }
		}
	}
	
	
	/**
	 * Returns the specified airport
	 * @param code Airport code
	 * @return Specified airport
	 */
	public Airport get(String code)
	{
		if (code.length() != 3 && code.length() != 4)
		{
			System.out.println("Error:\nInvalid airport code");
			System.exit(1);
		}
		else
		{
			try 
			{
				// Opens a connection 
				openConnection();
				
				// SQL query to be executed
				String criteria = (code.length() == 3) ? "airportiatacode" : "airporticaocode";
				String query = "SELECT * FROM airports WHERE " + criteria + " = '" + code + "'";
				stmt = conn.prepareStatement(query);
				
				// Airport to be returned
				Airport result = null;
				
				// Executes query
				ResultSet rs = stmt.executeQuery(query);
				while (rs.next())
				{
					result = new Airport();
					result.setAirportIATACode(rs.getString("airportiatacode"));
					result.setAirportICAOCode(rs.getString("airporticaocode"));
					result.setAirportName(rs.getString("airportname"));
					result.setAirportLocation(rs.getString("airportlocation"));
				}
				
				// Returns the specified airport
				if (result == null)
				{
					System.out.println("Error:\nAirport not found");
					System.exit(1);
				}
				
				return result;
			}
			catch (SQLException e) 
			{ 
				System.out.println("Error when searching airport:\n" + e.getMessage());
				System.exit(1);
			}
			catch (IOException e)
			{
				e.printStackTrace();
				System.exit(1);
			}
			finally
			{ closeConnection(); }
		}
		
		return null;
	}
	
	
	/**
	 * Returns all registered airports
	 * @return Registered airports
	 */
	public List<Airport> getAll()
	{
		try 
		{
			// Opens a connection 
			openConnection();
			
			// SQL query to be executed
			String query = "SELECT * FROM airports";
			
			// List of airports
			List<Airport> airports = new ArrayList<Airport>();
			
			// Executes query
			ResultSet rs = stmt.executeQuery(query);
			while (rs.next())
			{
				// Current airport
				Airport airport = new Airport();
				airport.setAirportIATACode(rs.getString("airportiatacode"));
				airport.setAirportICAOCode(rs.getString("airporticaocode"));
				airport.setAirportName(rs.getString("airportname"));
				airport.setAirportLocation(rs.getString("airportlocation"));
				
				// Adds the current airport
				airports.add(airport);
			}
			
			// Returns registered airports
			if (airports.isEmpty())
			{
				System.out.println("Error:\nNo airports registered");
				System.exit(1);
			}
			return airports;
		}
		catch (SQLException e) 
		{ 
			System.out.println("Error when searching airports:\n" + e.getMessage());
			System.exit(1);
		}
		catch (IOException e)
		{
			e.printStackTrace();
			System.exit(1);
		}
		finally
		{ closeConnection(); }
		
		return null;
	}
}
